#include "common_user_manager.h"
#include "common_config_manager.h"
#include "base_log.h"
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <chrono>

namespace El {
namespace Common {

UserManager &UserManager::GetInstance()
{
    static UserManager instance;
    return instance;
}

bool UserManager::Init()
{
    if (!LoadConfig()) {
        LOG_INFO("No user config found, creating default admin account");
        UserInfo adminUser;
        adminUser.username = DEFAULT_ADMIN_USERNAME;
        adminUser.password = EncryptPassword(DEFAULT_ADMIN_PASSWORD);
        adminUser.role = "admin";
        adminUser.enabled = true;
        adminUser.lastLoginTime =
            std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch())
                .count();
        users_.push_back(adminUser);
        return SaveConfig();
    }
    return true;
}

bool UserManager::Login(const std::string &username, const std::string &password)
{
    for (auto &user : users_) {
        if (user.username == username) {
            if (!user.enabled) {
                LOG_ERROR("User {} is disabled", username);
                return false;
            }

            // 解密存储的密码
            std::string storedPassword = DecryptPassword(user.password);
            if (storedPassword.empty()) {
                LOG_ERROR("Failed to decrypt password for user {}", username);
                return false;
            }

            // 直接比较明文密码
            if (password == storedPassword) {
                user.lastLoginTime = std::chrono::duration_cast<std::chrono::seconds>(
                                         std::chrono::system_clock::now().time_since_epoch())
                                         .count();
                return SaveConfig();
            }

            LOG_ERROR("Invalid password for user {}", username);
            return false;
        }
    }
    LOG_ERROR("User {} not found", username);
    return false;
}

bool UserManager::AddUser(const UserInfo &user)
{
    // 检查用户名是否已存在
    if (std::any_of(users_.begin(), users_.end(), [&](const UserInfo &u) { return u.username == user.username; })) {
        LOG_ERROR("User {} already exists", user.username);
        return false;
    }

    // 创建新用户，加密存储密码
    UserInfo newUser = user;
    newUser.password = EncryptPassword(user.password); // user.password是明文，需要加密存储
    newUser.lastLoginTime = 0;
    users_.push_back(newUser);
    return SaveConfig();
}

bool UserManager::DeleteUser(const std::string &username)
{
    if (username == DEFAULT_ADMIN_USERNAME) {
        LOG_ERROR("Cannot delete admin user");
        return false;
    }

    auto it =
        std::find_if(users_.begin(), users_.end(), [&](const UserInfo &user) { return user.username == username; });
    if (it == users_.end()) {
        LOG_ERROR("User {} not found", username);
        return false;
    }

    users_.erase(it);
    return SaveConfig();
}

bool UserManager::UpdateUser(const UserInfo &user)
{
    auto it =
        std::find_if(users_.begin(), users_.end(), [&](const UserInfo &u) { return u.username == user.username; });
    if (it == users_.end()) {
        LOG_ERROR("User {} not found", user.username);
        return false;
    }

    // 不允许修改admin用户的角色
    if (it->username == DEFAULT_ADMIN_USERNAME && user.role != "admin") {
        LOG_ERROR("Cannot change admin user role");
        return false;
    }

    it->role = user.role;
    it->enabled = user.enabled;
    return SaveConfig();
}

bool UserManager::GetUserInfo(const std::string &username, UserInfo &user)
{
    auto it = std::find_if(users_.begin(), users_.end(), [&](const UserInfo &u) { return u.username == username; });
    if (it == users_.end()) {
        LOG_ERROR("User {} not found", username);
        return false;
    }

    user = *it;
    // 解密密码
    std::string decryptedPassword = DecryptPassword(user.password);
    if (decryptedPassword.empty()) {
        LOG_ERROR("Failed to decrypt password for user {}", username);
        return false;
    }
    user.password = decryptedPassword;
    return true;
}

bool UserManager::GetUserList(std::vector<UserInfo> &users)
{
    users = users_;
    // 解密所有用户的密码
    for (auto &user : users) {
        std::string decryptedPassword = DecryptPassword(user.password);
        if (decryptedPassword.empty()) {
            LOG_ERROR("Failed to decrypt password for user {}", user.username);
            return false;
        }
        user.password = decryptedPassword;
    }
    return true;
}

bool UserManager::ChangePassword(const std::string &username,
                                 const std::string &oldPassword,
                                 const std::string &newPassword)
{
    auto it = std::find_if(users_.begin(), users_.end(), [&](const UserInfo &u) { return u.username == username; });
    if (it == users_.end()) {
        LOG_ERROR("User {} not found", username);
        return false;
    }

    // 解密存储的密码并与明文旧密码比较
    std::string storedPassword = DecryptPassword(it->password);
    if (storedPassword.empty()) {
        LOG_ERROR("Failed to decrypt password for user {}", username);
        return false;
    }

    if (oldPassword != storedPassword) {
        LOG_ERROR("Invalid old password for user {}", username);
        return false;
    }

    // 加密存储新密码
    it->password = EncryptPassword(newPassword);
    return SaveConfig();
}

bool UserManager::ResetPassword(const std::string &username)
{
    auto it = std::find_if(users_.begin(), users_.end(), [&](const UserInfo &u) { return u.username == username; });
    if (it == users_.end()) {
        LOG_ERROR("User {} not found", username);
        return false;
    }

    // 重置为默认密码
    it->password = EncryptPassword(DEFAULT_ADMIN_PASSWORD);
    return SaveConfig();
}

bool UserManager::SaveConfig()
{
    nlohmann::json config;
    for (const auto &user : users_) {
        nlohmann::json userJson;
        userJson["username"] = user.username;
        userJson["password"] = user.password;
        userJson["role"] = user.role;
        userJson["enabled"] = user.enabled;
        userJson["lastLoginTime"] = user.lastLoginTime;
        config["users"].push_back(userJson);
    }
    return ConfigManager::GetInstance().SetConfig("users", config);
}

bool UserManager::LoadConfig()
{
    auto config = ConfigManager::GetInstance().GetConfig("users");
    if (config.is_null()) {
        return false;
    }

    users_.clear();
    for (const auto &userJson : config["users"]) {
        UserInfo user;
        user.username = userJson["username"].get<std::string>();
        user.password = userJson["password"].get<std::string>();
        user.role = userJson["role"].get<std::string>();
        user.enabled = userJson["enabled"].get<bool>();
        user.lastLoginTime = userJson["lastLoginTime"].get<int64_t>();
        users_.push_back(user);
    }
    return true;
}

bool UserManager::ValidatePassword(const std::string &password, const std::string &encryptedPassword)
{
    std::string decryptedPassword = DecryptPassword(encryptedPassword);
    return !decryptedPassword.empty() && password == decryptedPassword;
}

std::string UserManager::EncryptPassword(const std::string &password)
{
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    if (!ctx) {
        LOG_ERROR("Failed to create cipher context");
        return "";
    }

    // 生成随机IV
    std::string iv = GenerateIV();
    if (iv.empty()) {
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    // 初始化加密上下文
    if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, GetEncryptionKey(),
                           reinterpret_cast<const unsigned char *>(iv.c_str())) != 1) {
        LOG_ERROR("Failed to initialize encryption");
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    // 计算加密后的长度
    int ciphertext_len;
    std::vector<unsigned char> ciphertext(password.length() + EVP_MAX_BLOCK_LENGTH);

    // 加密数据
    if (EVP_EncryptUpdate(ctx, ciphertext.data(), &ciphertext_len,
                          reinterpret_cast<const unsigned char *>(password.c_str()), password.length()) != 1) {
        LOG_ERROR("Failed to encrypt data");
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    // 处理最后的数据块
    int final_len;
    if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + ciphertext_len, &final_len) != 1) {
        LOG_ERROR("Failed to finalize encryption");
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    EVP_CIPHER_CTX_free(ctx);

    // 将IV和密文组合成最终的加密结果
    std::string result = iv;
    result.append(reinterpret_cast<char *>(ciphertext.data()), ciphertext_len + final_len);

    // 将结果转换为Base64编码
    std::stringstream ss;
    for (char c : result) {
        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(static_cast<unsigned char>(c));
    }
    return ss.str();
}

std::string UserManager::DecryptPassword(const std::string &encryptedPassword)
{
    // 将十六进制字符串转换回二进制数据
    std::string binary;
    for (size_t i = 0; i < encryptedPassword.length(); i += 2) {
        std::string byte = encryptedPassword.substr(i, 2);
        char chr = static_cast<char>(std::stoi(byte, nullptr, 16));
        binary.push_back(chr);
    }

    // 提取IV（前16字节）
    if (binary.length() < 16) {
        LOG_ERROR("Invalid encrypted password format");
        return "";
    }
    std::string iv = binary.substr(0, 16);
    std::string ciphertext = binary.substr(16);

    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    if (!ctx) {
        LOG_ERROR("Failed to create cipher context");
        return "";
    }

    // 初始化解密上下文
    if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, GetEncryptionKey(),
                           reinterpret_cast<const unsigned char *>(iv.c_str())) != 1) {
        LOG_ERROR("Failed to initialize decryption");
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    // 计算解密后的长度
    std::vector<unsigned char> plaintext(ciphertext.length());
    int plaintext_len;

    // 解密数据
    if (EVP_DecryptUpdate(ctx, plaintext.data(), &plaintext_len,
                          reinterpret_cast<const unsigned char *>(ciphertext.c_str()), ciphertext.length()) != 1) {
        LOG_ERROR("Failed to decrypt data");
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    // 处理最后的数据块
    int final_len;
    if (EVP_DecryptFinal_ex(ctx, plaintext.data() + plaintext_len, &final_len) != 1) {
        LOG_ERROR("Failed to finalize decryption");
        EVP_CIPHER_CTX_free(ctx);
        return "";
    }

    EVP_CIPHER_CTX_free(ctx);

    return std::string(reinterpret_cast<char *>(plaintext.data()), plaintext_len + final_len);
}

std::string UserManager::GenerateIV()
{
    unsigned char iv[16];
    if (RAND_bytes(iv, sizeof(iv)) != 1) {
        LOG_ERROR("Failed to generate random IV");
        return "";
    }
    return std::string(reinterpret_cast<char *>(iv), sizeof(iv));
}

const unsigned char *UserManager::GetEncryptionKey()
{
    return ENCRYPTION_KEY;
}

} // namespace Common
} // namespace El